//
//  MYGHealthManager.swift
//  MYGrow
//
//  Created by 林矗 on 2024/4/6.
//

import UIKit
import Dispatch
class MYGHealthManager {
    static let `shareManager` = MYGHealthManager()
    private var pressureDatas: [MYGHealthStastiscPressureModel]?
    private var heartDatas: [MYGHealthStastiscHeartModel]?
    private var bmiDatas: [MYGHealthStastiscBMIModel]?
    private var sugarDatas: [MYGHealthStastiscSugarModel]?
    var userInfo: MYGHealthManagementUserInfoModel?
    var patientId: String = "0"
    func loadData(completion: (() -> ())?) {
        let group = DispatchGroup()
        group.enter()
        loadPressureData { group.leave() }
        group.enter()
        loadHeartRateData { group.leave() }
        group.enter()
        loadSugarData { group.leave() }
        group.enter()
        loadBMIData { group.leave() }
        group.notify(queue: .main) { completion?() }
    }
    
    // MARK: Pressure
    private func loadPressureData(completion: (() -> ())?) {
        MYGNetwork<MYGHealthApi, MYGPageModel<MYGHealthStastiscPressureModel>>.request(target: .bloodPressureList(startDate: nil, endDate: nil, page: 1, patientId: patientId)) {[weak self] result in
            guard let self = self else { return }
            self.pressureDatas = result.list
            completion?()
        } failed: { _, error in
            completion?()
        }
    }
    
    private func getTodayPressureData() -> MYGHealthStastiscPressureModel? {
        guard let pressureDatas = pressureDatas, pressureDatas.count > 0 else { return nil }
        let todayRecords = pressureDatas.filter { model in
            guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
            return measureDate.dateAtStartOf(.day) == Date().dateAtStartOf(.day)
        }
        return todayRecords.last
    }
    
    func getPressureData(componet: Calendar.Component? = nil, type: Int = 1, completion: (([MYGHealthStastiscPressureModel]? , MYGHealthStastiscPressureModel?) -> ())?) {
//        if let pressureDatas = pressureDatas {
//            completion?(pressureListData(componet: componet, type: type), getTodayPressureData())
//            return
//        }
        
        pressureDatas = nil
        
        loadPressureData {
            completion?(self.pressureListData(componet: componet, type: type), self.getTodayPressureData())
        }
    }
    
    private func pressureListData(componet: Calendar.Component? = nil, type: Int = 0) -> [MYGHealthStastiscPressureModel]? {
        guard let pressureDatas = pressureDatas else { return nil }
        if let componet = componet {
            var datas: [MYGHealthStastiscPressureModel] = []
            if componet == .day {
                datas = pressureDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.day) == Date().dateAtStartOf(.day)
                })
            } else if componet == .weekday {
                datas = pressureDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.weekday) == Date().dateAtStartOf(.weekday)
                })
            } else if componet == .month {
                datas = pressureDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.month) == Date().dateAtStartOf(.month)
                })
            }
            if type == 0 {
                return datas
            } else {
                return datas.suffix(7)
            }
            
        } else {
            if type == 0 {
                return pressureDatas
            } else {
                return pressureDatas.suffix(7)
            }
        }
    }
    
    // MARK: Heart Rate
    private func loadHeartRateData(completion: (() -> ())?) {
        MYGNetwork<MYGHealthApi, MYGPageModel<MYGHealthStastiscHeartModel>>.request(target: .heartRateList(startDate: nil, endDate: nil, page: 1, pageSize: nil, patientId: patientId)) {[weak self] result in
            defer {
                completion?()
            }
            guard let self = self else { return }
            self.heartDatas = result.list
        } failed: { _, error in
            completion?()
        }
    }
    
    private func getTodayHeartRateData() -> MYGHealthStastiscHeartModel? {
        guard let heartDatas = heartDatas, heartDatas.count > 0 else { return nil }
        let todayRecords = heartDatas.filter { model in
            guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
            return measureDate.dateAtStartOf(.day) == Date().dateAtStartOf(.day)
        }
        return todayRecords.last
    }
    
    func getHeartRateData(componet: Calendar.Component? = nil, type: Int = 1, completion: (([MYGHealthStastiscHeartModel]? , MYGHealthStastiscHeartModel?) -> ())?) {
//        if let heartDatas = heartDatas {
//            completion?(heartRateData(componet: componet, type: type), getTodayHeartRateData())
//            return
//        }
        heartDatas = nil
        
        loadHeartRateData {
            completion?(self.heartRateData(componet: componet, type: type), self.getTodayHeartRateData())
        }
    }
    
    private func heartRateData(componet: Calendar.Component? = nil, type: Int = 0) -> [MYGHealthStastiscHeartModel]? {
        guard let heartDatas = heartDatas else { return nil }
        if let componet = componet {
            var datas: [MYGHealthStastiscHeartModel] = []
            if componet == .day {
                datas = heartDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.day) == Date().dateAtStartOf(.day)
                })
            } else if componet == .weekday {
                datas = heartDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.weekday) == Date().dateAtStartOf(.weekday)
                })
            } else if componet == .month {
                datas = heartDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.month) == Date().dateAtStartOf(.month)
                })
            }
            if type == 0 {
                return datas
            } else {
                return datas.suffix(7)
            }
            
        } else {
            if type == 0 {
                return heartDatas
            } else {
                return heartDatas.suffix(7)
            }
        }
    }
    
    // MARK: Sugar
    private func loadSugarData(completion: (() -> ())?) {
        MYGNetwork<MYGHealthApi, MYGPageModel<MYGHealthStastiscSugarModel>>.request(target: .sugarList(startDate: nil, endDate: nil, page: 1, pageSize: nil, patientId: patientId)) {[weak self] result in
            defer {
                completion?()
            }
            guard let self = self else { return }
            self.sugarDatas = result.list
        } failed: { _, error in
            completion?()
        }
    }
    
    private func getTodaySugarData() -> MYGHealthStastiscSugarModel? {
        guard let sugarDatas = sugarDatas, sugarDatas.count > 0 else { return nil }
        let todayRecords = sugarDatas.filter { model in
            guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
            return measureDate.dateAtStartOf(.day) == Date().dateAtStartOf(.day)
        }
        return todayRecords.last
    }
    
    func getSugarData(componet: Calendar.Component? = nil, type: Int = 1, completion: (([MYGHealthStastiscSugarModel]? , MYGHealthStastiscSugarModel?) -> ())?) {
//        if let sugarDatas = sugarDatas {
//            completion?(sugarData(componet: componet, type: type), getTodaySugarData())
//            return
//        }
        sugarDatas = nil
        
        loadSugarData {
            completion?(self.sugarData(componet: componet, type: type), self.getTodaySugarData())
        }
    }
    
    private func sugarData(componet: Calendar.Component? = nil, type: Int = 0) -> [MYGHealthStastiscSugarModel]? {
        guard let sugarDatas = sugarDatas else { return nil }
        if let componet = componet {
            var datas: [MYGHealthStastiscSugarModel] = []
            if componet == .day {
                datas = sugarDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.day) == Date().dateAtStartOf(.day)
                })
            } else if componet == .weekday {
                datas = sugarDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.weekday) == Date().dateAtStartOf(.weekday)
                })
            } else if componet == .month {
                datas = sugarDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.month) == Date().dateAtStartOf(.month)
                })
            }
            if type == 0 {
                return datas
            } else {
                return datas.suffix(7)
            }
            
        } else {
            if type == 0 {
                return sugarDatas
            } else {
                return sugarDatas.suffix(7)
            }
        }
    }
    
    // MARK: BMI
    private func loadBMIData(completion: (() -> ())?) {
        MYGNetwork<MYGHealthApi, MYGPageModel<MYGHealthStastiscBMIModel>>.request(target: .bmiList(startDate: nil, endDate: nil, page: 1, pageSize: nil, patientId: patientId)) {[weak self] result in
            defer {
                completion?()
            }
            guard let self = self else { return }
            self.bmiDatas = result.list
        } failed: { _, error in
            completion?()
        }
    }
    
    private func getTodayBMIData() -> MYGHealthStastiscBMIModel? {
        guard let bmiDatas = bmiDatas, bmiDatas.count > 0 else { return nil }
        let todayRecords = bmiDatas.filter { model in
            guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
            return measureDate.dateAtStartOf(.day) == Date().dateAtStartOf(.day)
        }
        return todayRecords.last
    }
    
    func getBMIData(componet: Calendar.Component? = nil, type: Int = 1, completion: (([MYGHealthStastiscBMIModel]? , MYGHealthStastiscBMIModel?) -> ())?) {
//        if let bmiDatas = bmiDatas {
//            completion?(bmiData(componet: componet, type: type), getTodayBMIData())
//            return
//        }
        bmiDatas = nil
        loadSugarData {
            completion?(self.bmiData(componet: componet, type: type), self.getTodayBMIData())
        }
    }
    
    private func bmiData(componet: Calendar.Component? = nil, type: Int = 0) -> [MYGHealthStastiscBMIModel]? {
        guard let bmiDatas = bmiDatas else { return nil }
        if let componet = componet {
            var datas: [MYGHealthStastiscBMIModel] = []
            if componet == .day {
                datas = bmiDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.day) == Date().dateAtStartOf(.day)
                })
            } else if componet == .weekday {
                datas = bmiDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.weekday) == Date().dateAtStartOf(.weekday)
                })
            } else if componet == .month {
                datas = bmiDatas.filter({ model in
                    guard let measureDate = model.measure_at.date(withFormat: "yyyy-MM-dd HH:mm:ss") else { return false }
                    return measureDate.dateAtStartOf(.month) == Date().dateAtStartOf(.month)
                })
            }
            if type == 0 {
                return datas
            } else {
                return datas.suffix(7)
            }
            
        } else {
            if type == 0 {
                return bmiDatas
            } else {
                return bmiDatas.suffix(7)
            }
        }
    }
}


// MARK: 健康管理小项
extension MYGHealthManager {
    func loadUser(completion: (() -> ())?) {
        MYGNetwork<MYGHealthApi, MYGHealthManagementUserInfoModel>.request(target: .userInfo(patientId: patientId)) { result in
            self.userInfo = result
            completion?()
        } failed: { _, error in
            MMYGHUD.showToast(text: error)
            completion?()
        }
    }
    
    func getCurrentUser() -> MYGHealthManagementUserInfoModel? {
        return userInfo
    }
    
    func getHistoryItem(with type: MYGHealthManagementLocalEventType) -> [String] {
        if let patient = userInfo {
            switch type {
            case .smoke:
                if patient.smoking == 1 {
                    return ["从不吸烟"]
                } else if patient.smoking == 2 {
                    return ["已戒烟"]
                } else if patient.smoking == 3 {
                    return ["现仍在吸烟"]
                } else {
                    return ["未知"]
                }
            case .drink:
                if patient.drinking == 1 {
                    return ["从不饮酒"]
                } else if patient.drinking == 2 {
                    return ["已戒酒"]
                } else if patient.drinking == 3 {
                    return ["现仍在饮酒"]
                } else {
                    return ["未知"]
                }
            case .sleep:
                return [patient.days_insufficient_sleep]
            case .touch:
                return [patient.contact_history]
            case .ill:
                return patient.historyDisease
            case .family:
                return patient.familyHistoryDisease
            case .op:
                return patient.surgical_history
            case .medical:
                return patient.medication_history
            case .allergy:
                return patient.allergy
            }
        }
        
        return []
    }
}
